const { app, BrowserWindow, ipcMain, Menu, dialog, Tray } = require("electron");
const path = require("path");
app.commandLine.appendSwitch("disable-site-isolation-trials");
const { exec, spawn } = require("child_process");
//Menu.setApplicationMenu(null)

let win_main, win_setbot;
let false_close = false;
let tray = null;
const processManager = createProcessManager();

const file = read_data(path.resolve(), "file");

if (file.file_data == "") {
    file.file_data = path.join(path.resolve(), "config");
    write_data(path.resolve(), "file", file);
}

const json_file = path.join(file.file_data, "data");

const Profiles = read_data(json_file, "Profiles");
false_close = Profiles.false_close;

const window_template = {
    width: 1000,
    height: 600,
    resizable: false,
    frame: false,
    autoHideMenuBar: true,
    transparent: true,
    webPreferences: {
        nodeIntegration: true,
        contextIsolation: false,
    },
};

//主渲染进程的有关代码

const createWindow = () => {
    window_template.icon = path.join(__dirname, "data", "logo", "logo.ico");
    win_main = new BrowserWindow(window_template);
    win_main.loadFile("./html/index/index.html");
    win_main.on("close", (event) => {
        if (false_close) {
            win_main.hide();
            win_main.setSkipTaskbar(true);
            event.preventDefault();
        } else {
            win_main = null;
        }
    });

    tray = new Tray(path.join(__dirname, "data", "logo", "logo.ico"));
    const contextMenu = Menu.buildFromTemplate([
        {
            label: "退出",
            click: () => {
                false_close = false;
                win_main.close();
            },
        },
    ]);
    tray.setToolTip("晓易崽");
    tray.setContextMenu(contextMenu);
    tray.on("click", () => {
        //我们这里模拟桌面程序点击通知区图标实现打开关闭应用的功能
        win_main.isVisible() ? win_main.hide() : win_main.show();
        win_main.isVisible() ? win_main.setSkipTaskbar(false) : win_main.setSkipTaskbar(true);
    });
};

//程序准备好时
app.on("ready", () => {
    createWindow();
});

//程序关闭
app.on("window-all-closed", () => {
    // 关闭所有进程
    processManager.kill();
    setTimeout(function () {
        app.quit();
    }, 1000);
});

//窗口拖拽
ipcMain.on("move-application", (ev, data) => {
    win_main.setBounds({ x: data.posX, y: data.posY, width: 1000, height: 600 });
});

//处理最小化与关闭
ipcMain.on("close", (ev) => {
    win_main.close();
});

ipcMain.on("minimize", () => {
    win_main.minimize();
});

ipcMain.on("false_close", (ev, data) => {
    false_close = data;
});

//添加bot的有关代码

//添加bot窗口
ipcMain.on("add_bot", () => {
    window_template.parent = BrowserWindow.fromId(win_main.id);
    window_template.modal = true;
    window_template.width = 450;
    window_template.height = 550;
    win_setbot = new BrowserWindow(window_template);
    win_setbot.loadFile("./html/setbot/setbot.html");
    win_setbot.on("closed", () => {
        win_setbot = null;
    });
});

//处理新窗口关闭
ipcMain.on("close_add_bot", (ev, data) => {
    win_setbot.close();
    win_main.webContents.send("refresh_bot_left", data);
});

ipcMain.on("addbot_dialog_path", (ev, data) => {
    const dialog_path = dialog.showOpenDialogSync(win_setbot, {
        title: data,
        defaultPath: path.resolve(),
        buttonLabel: "导入",
        properties: ["openFile", "openDirectory"],
    });
    ev.sender.send("dialog_path", dialog_path);
});

ipcMain.on("execute_add_bot", (ev, data) => {
    const simpleGit = require("simple-git");
    const git = simpleGit();
    const url = path.join(file.file_data, "yunzai", "Yunzai-" + data.id);

    git
        .clone(data.url, url)
        .then(() => {
            const pnpmi = exec("pnpm i", { cwd: url });

            pnpmi.on("exit", () => {
                exec("node app", { cwd: url });
                win_main.webContents.send("git_add_true", data.id);
            });
        })
        .catch((err) => console.log("no:" + err));
});

ipcMain.on("open_bot_exec", (ev, data) => {
    // 启动进程
    const bot = processManager.startProcesses(data);
    if (!bot) return;
    bot.nodeProcess.stdout.on("data", (log) => {
        const str = log.toString();

        ev.sender.send("bot_exec", {
            id: data.id,
            data: str,
        });
    });
});

ipcMain.on("close_bot_exec", (ev, data) => {
    // 关闭特定ID的进程
    processManager.killProcessesById(data);
});

ipcMain.on("user_thing", (ev, data) => {
    processManager.inputProcessesById(data.id, data.input)
})

//函数方法

function createProcessManager() {
    const processes = new Map(); // 用于存储进程信息，键是ID，值是{ redis: childProcess, node: childProcess }

    // 启动Redis和Node应用
    function startProcesses(data) {
        const { id, redis_port, bot_path } = data;
        const processInfo = processes.get(id);
        if (processInfo) return false;
        // 使用spawn启动redis-server.exe，并传入端口号
        const redis_file = path.join(__dirname, "data", "Redis");
        const redisProcess = spawn("./redis-server.exe", ["--port", redis_port], { cwd: redis_file });
        // 使用spawn启动node应用
        let bot_file
        if (!bot_path) bot_file = path.join(file.file_data, "yunzai", `Yunzai-${id}`);
        else bot_file = bot_path
        const env = {
            ...process.env, // 复制当前进程的环境变量  
            FORCE_TTY: '1'  // 添加或覆盖 FORCE_TTY 环境变量  
        };
        const nodeProcess = spawn("node", ["app.js"], { cwd: bot_file, env: env });

        // 将进程信息存储到processes Map中
        processes.set(id, { redis: redisProcess, node: nodeProcess });

        // 返回进程对象，以便外部可以访问（如果需要）
        return { redisProcess, nodeProcess };
    }

    //输入指令
    function inputProcessesById(id, directives) {
        const processInfo = processes.get(id);
        if (!processInfo) return;
        const { node } = processInfo;
        node.stdin.write(`${directives}\r\n`);
    }

    // 关闭特定ID的进程
    function killProcessesById(id) {
        const processInfo = processes.get(id);
        if (!processInfo) return;
        const { redis, node } = processInfo;
        // 如果redis进程存在，则发送SIGTERM信号来关闭它
        if (redis) redis.kill("SIGTERM");
        // 如果node进程存在，则发送SIGTERM信号来关闭它
        if (node) node.kill("SIGTERM");
        // 从processes Map中删除该ID的进程信息
        processes.delete(id);
    }

    // 关闭所有进程
    function kill() {
        // 遍历processes Map中的所有进程信息
        for (const { redis, node } of processes.values()) {
            // 如果redis进程存在，则发送SIGTERM信号来关闭它
            if (redis) redis.kill("SIGTERM");
            // 如果node进程存在，则发送SIGTERM信号来关闭它
            if (node) node.kill("SIGTERM");
        }
        // 清空processes Map
        processes.clear();
    }

    // 返回需要的函数
    return {
        startProcesses,
        inputProcessesById,
        killProcessesById,
        kill,
    };
}

//读取文件
function read_data(file, data) {
    const fs = require("fs");
    const dir = path.join(file, `${data}.json`);
    let enroll = fs.readFileSync(dir, "utf8", (err, data) => {
        if (err) {
            console.log(err);
            return "error";
        }
        return data;
    });
    //将字符串数据转变成数组格式
    enroll = JSON.parse(enroll);
    return enroll;
}

function write_data(file, data, enroll) {
    const fs = require("fs");
    const dir = path.join(file, `${data}.json`);
    const new_ARR = JSON.stringify(enroll, "", "\t");
    fs.writeFileSync(dir, new_ARR, "utf8", (err) => {
        console.log("写入成功", err);
    });
    return;
}
